package com.ziytek.web.citizen.util;

import com.ziytek.web.citizen.constant.NumConstant;
import com.ziytek.web.citizen.model.bean.DeviceRequestModel;
import com.ziytek.web.citizen.model.data.BatteryDetail;
import com.ziytek.web.citizen.model.data.CommandResponse;
import com.ziytek.web.citizen.model.data.OneBattery;
import com.ziytek.web.citizen.model.data.RealData;
import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;

/**
 * @author fengh
 */
@Slf4j
public class DataUtils {

    private static final Integer LENGTH_BYTE = 43;
    private static final Integer LENGTH_BYTE_ONE = 40;
    private static final Integer LENGTH_HEX_SIXTY = 16;

    public static RealData parseRealData(byte[] data) {
        ByteBuffer byteBuffer = ByteBuffer.wrap(data);
        // 2762
        // 读取通信头 1-字节 通信头 0xAA
        var head = byteBuffer.get() & 0xFF;

        // 读取通信板的地址 1-字节 0X00-0XFF
        var boardAddress = byteBuffer.get() & 0xFF;

        // 读取主控版本号 1-字节 0X00-0XFF
        var mainControlVersion = byteBuffer.get() & 0xFF;

        // 读取数据类型 1-字节 0X00-0XFF
        var dataType = byteBuffer.get() & 0xFF;

        // 读取数据负载长度 2-字节 0x0000-0xFFFF
        var low = byteBuffer.get() & 0xFF;
        var high = byteBuffer.get() & 0xFF;
        var loadLengthHex = Integer.toHexString(high) + Integer.toHexString(low);
        var loadLength = Integer.parseInt(loadLengthHex, LENGTH_HEX_SIXTY);
        //log.info("loadLengthHex:{},loadLength:{}", loadLengthHex, loadLength);

        // 读取数据负载 N-字节
        byte[] loadData = new byte[loadLength];
        byteBuffer.get(loadData);

        // 读取XOR校验码 1-字节
        var xorCode = byteBuffer.get() & 0xFF;

        // 读取数据尾 1-字节 0xCC
        var dataTail = byteBuffer.get() & 0xFF;

        return new RealData(data, head, boardAddress, parseBatteryDetailList(loadData), dataType);
    }


    public static CommandResponse commandResponse(byte[] data) {
        ByteBuffer byteBuffer = ByteBuffer.wrap(data);
        // 读取通信头 1-字节 通信头 0xAA
        var head = byteBuffer.get() & 0xFF;

        // 读取通信板的地址 1-字节 0X00-0XFF
        var boardAddress = byteBuffer.get() & 0xFF;

        // 读取主控版本号 1-字节 0X00-0XFF
        var version = byteBuffer.get() & 0xFF;

        // 数据类型 1-字节 0X00-0XFF
        var type = byteBuffer.get() & 0xFF;

        // 读取数据负载长度 2-字节 0x0000-0xFFFF
        var low = byteBuffer.get() & 0xFF;
        var high = byteBuffer.get() & 0xFF;
        var loadLengthHex = Integer.toHexString(high) + Integer.toHexString(low);
        var loadLength = Integer.parseInt(loadLengthHex, LENGTH_HEX_SIXTY);
        //log.info("loadLengthHex:{},loadLength:{}", loadLengthHex, loadLength);

        // 是否成功 1-字节
        var success = byteBuffer.get() & 0xFF;

        // 消息唯一标识 2-字节
        var messageOffset = byteBuffer.get() & 0XFF;
        var messageEnd = byteBuffer.get() & 0XFF;
        var message = Integer.toHexString(messageOffset) + Integer.toHexString(messageEnd);
        message = HexUtil.fillZero(message, NumConstant.INT_FOUR);

        // 读取XOR校验码 1-字节
        var xorCode = byteBuffer.get() & 0xFF;

        // 读取数据尾 1-字节 0xCC
        var end = byteBuffer.get() & 0xFF;

        return new CommandResponse(type, head, boardAddress, version, loadLength, success, message, xorCode, end);
    }


    public static DeviceRequestModel parseDeviceRequest(byte[] data) {
        ByteBuffer byteBuffer = ByteBuffer.wrap(data);
        // 读取通信头 1-字节 通信头 0xAA
        var head = byteBuffer.get() & 0xFF;

        // 读取通信板的地址 1-字节 0X00-0XFF
        var boardAddress = byteBuffer.get() & 0xFF;

        // 读取主控版本号 1-字节 0X00-0XFF
        var version = byteBuffer.get() & 0xFF;

        // 数据类型 1-字节 0X00-0XFF
        var type = byteBuffer.get() & 0xFF;

        var length = byteBuffer.get() & 0xFF;
        var lengthTwo = byteBuffer.get() & 0xFF;

        // 读取数据负载长度 2-字节 0x0000-0xFFFF
        var s1 = byteBuffer.get() & 0xFF;
        var s2 = byteBuffer.get() & 0xFF;
        var loadLengthHex = HexUtil.fillZero(Integer.toHexString(s1), NumConstant.INT_TWO) +
                HexUtil.fillZero(Integer.toHexString(s2), NumConstant.INT_TWO);
        var load = Integer.parseInt(loadLengthHex, LENGTH_HEX_SIXTY);

        return new DeviceRequestModel(head, boardAddress, type, load);
    }

    private static List<BatteryDetail> parseBatteryDetailList(byte[] data) {
        if (data == null || data.length != NumConstant.INT_SIX_EIGHT_EIGHT) {
            return null;
        }

        ByteBuffer byteBuffer = ByteBuffer.wrap(data);
        List<BatteryDetail> batteryDetailList = new ArrayList<>();

        for (int i = NumConstant.INT_ZERO; i < NumConstant.INT_SIXTY_FOUR / NumConstant.INT_FOUR; i++) {
            byte[] loadData = new byte[LENGTH_BYTE];
            byteBuffer.get(loadData);
            batteryDetailList.add(parseBatteryDetail(loadData));
        }

        return batteryDetailList;
    }

    private static BatteryDetail parseBatteryDetail(byte[] data) {
        ByteBuffer byteBuffer = ByteBuffer.wrap(data);

        // 分控板地址 1-字节  0xAA
        var controlBoardAddress = byteBuffer.get() & 0XFF;

        // 分控板的电芯数量 1-字节  0xAA
        var batteryNumber = byteBuffer.get() & 0XFF;

        // 版本 1-字节  0xAA
        var version = byteBuffer.get() & 0XFF;

        // 读取数据负载 N-字节
        byte[] loadData = new byte[LENGTH_BYTE_ONE];
        byteBuffer.get(loadData);

        return new BatteryDetail(controlBoardAddress, batteryNumber, version, parseOneBatteryList(loadData));
    }

    private static List<OneBattery> parseOneBatteryList(byte[] data) {
        if (data == null || data.length != LENGTH_BYTE_ONE) {
            return null;
        }

        ByteBuffer byteBuffer = ByteBuffer.wrap(data);
        List<OneBattery> oneBatteries = new ArrayList<>();
        for (int i = NumConstant.INT_ZERO; i < NumConstant.INT_EIGHT; i++) {
            byte[] loadData = new byte[NumConstant.INT_FIVE];
            byteBuffer.get(loadData);
            oneBatteries.add(parseOneBattery(loadData));
        }

        return oneBatteries;
    }

    private static OneBattery parseOneBattery(byte[] data) {
        ByteBuffer byteBuffer = ByteBuffer.wrap(data);

        // 位置 1-字节  0xAA
        var position = byteBuffer.get() & 0XFF;

        // 电流 2-字节  0xAA00
        byte[] bigEndianData = new byte[NumConstant.INT_TWO];
        byteBuffer.get(bigEndianData);
        short current = S16Parser.parseS16(bigEndianData, 0, ByteOrder.BIG_ENDIAN);

        // 电压 2-字节  0xAA00
        byte[] bigEndianData2 = new byte[NumConstant.INT_TWO];
        byteBuffer.get(bigEndianData2);
        short voltage = S16Parser.parseS16(bigEndianData2, 0, ByteOrder.BIG_ENDIAN);

        return new OneBattery(position, (int) current, (int) voltage);
    }


}
